package org.goodsmanager.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.goodsmanager.entity.Product;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * Excel导出工具类
 *
 * @author Goods Manager System
 * @version 1.0.0
 */
@Slf4j
public class ExcelExportUtil {

    private static final DateTimeFormatter DATE_TIME_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 导出商品列表到Excel
     */
    public static void exportProductsToExcel(List<Product> products,
                                             HttpServletResponse response) throws IOException {
        // 创建工作簿
        try (Workbook workbook = new XSSFWorkbook()) {
            // 创建工作表
            Sheet sheet = workbook.createSheet("商品列表");

            // 创建样式
            CellStyle headerStyle = createHeaderStyle(workbook);
            CellStyle dataStyle = createDataStyle(workbook);

            // 创建表头
            Row headerRow = sheet.createRow(0);
            String[] headers = {
                    "商品ID", "商品名称", "商品编码", "分类", "品牌",
                    "规格", "单位", "进货价", "销售价", "库存数量",
                    "最小库存", "状态", "销量", "浏览量", "创建时间"
            };

            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }

            // 填充数据
            int rowNum = 1;
            for (Product product : products) {
                Row row = sheet.createRow(rowNum++);

                createCell(row, 0, product.getId(), dataStyle);
                createCell(row, 1, product.getProductName(), dataStyle);
                createCell(row, 2, product.getProductCode(), dataStyle);
                createCell(row, 3, product.getCategoryName(), dataStyle);
                createCell(row, 4, product.getBrand(), dataStyle);
                createCell(row, 5, product.getSpecification(), dataStyle);
                createCell(row, 6, product.getUnit(), dataStyle);
                createCell(row, 7, product.getPurchasePrice() != null ?
                        product.getPurchasePrice().toString() : "", dataStyle);
                createCell(row, 8, product.getSalePrice() != null ?
                        product.getSalePrice().toString() : "", dataStyle);
                createCell(row, 9, product.getStockQuantity() != null ?
                        product.getStockQuantity().toString() : "", dataStyle);
                createCell(row, 10, product.getMinStock() != null ?
                        product.getMinStock().toString() : "", dataStyle);
                createCell(row, 11, product.getStatusText(), dataStyle);
                createCell(row, 12, product.getSalesCount() != null ?
                        product.getSalesCount().toString() : "", dataStyle);
                createCell(row, 13, product.getViewCount() != null ?
                        product.getViewCount().toString() : "", dataStyle);
                createCell(row, 14, product.getCreatedAt() != null ?
                        product.getCreatedAt().format(DATE_TIME_FORMATTER) : "", dataStyle);
            }

            // 自动调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
                // 额外增加一些宽度
                sheet.setColumnWidth(i, sheet.getColumnWidth(i) + 1000);
            }

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String fileName = "商品列表_" + System.currentTimeMillis() + ".xlsx";
            String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
            response.setHeader("Content-Disposition",
                    "attachment; filename=\"" + encodedFileName + "\"");

            // 写入输出流
            try (OutputStream out = response.getOutputStream()) {
                workbook.write(out);
                out.flush();
            }

            log.info("导出商品列表成功，共{}条记录", products.size());
        } catch (Exception e) {
            log.error("导出Excel失败", e);
            throw new IOException("导出Excel失败: " + e.getMessage(), e);
        }
    }

    /**
     * 创建表头样式
     */
    private static CellStyle createHeaderStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();

        // 设置背景色
        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        // 设置边框
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);

        // 设置对齐方式
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);

        // 设置字体
        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontHeightInPoints((short) 12);
        style.setFont(font);

        return style;
    }

    /**
     * 创建数据样式
     */
    private static CellStyle createDataStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();

        // 设置边框
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);

        // 设置对齐方式
        style.setAlignment(HorizontalAlignment.LEFT);
        style.setVerticalAlignment(VerticalAlignment.CENTER);

        // 设置自动换行
        style.setWrapText(true);

        return style;
    }

    /**
     * 创建单元格并设置值和样式
     */
    private static void createCell(Row row, int column, String value, CellStyle style) {
        Cell cell = row.createCell(column);
        cell.setCellValue(value != null ? value : "");
        cell.setCellStyle(style);
    }
}